package com.nsu.cl.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.nsu.cl.common.Base;
import com.nsu.cl.pojo.Admin;
import com.nsu.cl.pojo.LoginForm;
import com.nsu.cl.pojo.Student;
import com.nsu.cl.pojo.Teacher;
import com.nsu.cl.service.AdminService;
import com.nsu.cl.service.StudentService;
import com.nsu.cl.service.TeacherService;
import com.nsu.cl.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

@Api(tags = "系统控制器")
@RestController
@RequestMapping("/sys")
public class SystemController {

    @Autowired
    private AdminService adminService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private TeacherService teacherService;

    String code;
    
    /*
        修改密码的处理器
        POST /sms/system/updatePwd/123456/admin
        POST /sms/system/updatePwd/{oldPwd}/{newPwd}
        请求参数
            odlPwd newPwd
            token 头
        响应的数据
            Result OK data = null
     */

    @ApiOperation("更新用户密码的返回")
    @PostMapping("/updatePwd/{oldPwd}/{newPwd}")
    public Result updatePwd(@ApiParam("token口令") @RequestHeader("token") String token,
                            @ApiParam("旧密码") @PathVariable("oldPwd") String oldPwd,
                            @ApiParam("新密码") @PathVariable("newPwd") String newPwd) {
        boolean expiration = JwtHelper.isExpiration(token);
        if (expiration) {
            // token过期
            return Result.fail().message("token失效,请重新登录后再修改密码.");
        }
        // 获取用户id和类型
        Long userId = JwtHelper.getUserId(token);
        Integer userType = JwtHelper.getUserType(token);

        oldPwd = MD5.encrypt(oldPwd);
        newPwd = MD5.encrypt(newPwd);

        switch (userType) {
            case 1 :
                QueryWrapper<Admin> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("id",userId.intValue());
                queryWrapper1.eq("password", oldPwd);
                Admin admin = adminService.getOne(queryWrapper1);
                if (admin != null) {
                    // 修改
                    admin.setPassword(newPwd);
                    adminService.saveOrUpdate(admin);
                }else {
                    return Result.fail().message("原密码有误");
                }
                break;
            case 2 :
                QueryWrapper<Student> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("id",userId.intValue());
                queryWrapper2.eq("password", oldPwd);
                Student student = studentService.getOne(queryWrapper2);
                if (student != null) {
                    // 修改
                    student.setPassword(newPwd);
                    studentService.saveOrUpdate(student);
                }else {
                    return Result.fail().message("原密码有误");
                }
                break;
            case 3 :
                QueryWrapper<Teacher> queryWrapper3 = new QueryWrapper<>();
                queryWrapper3.eq("id",userId.intValue());
                queryWrapper3.eq("password", oldPwd);
                Teacher teacher = teacherService.getOne(queryWrapper3);
                if (teacher != null) {
                    // 修改
                    teacher.setPassword(newPwd);
                    teacherService.saveOrUpdate(teacher);
                }else {
                    return Result.fail().message("原密码有误");
                }
                break;
        }

        return Result.ok();
    }

    @ApiOperation("根据ID查个人信息")
    @GetMapping("/getInfoByType")
    public Result getInfoByType(@ApiParam("token口令") @RequestHeader("token") String token) {
        boolean expiration = JwtHelper.isExpiration(token);
        if (expiration) {
            // token过期
            return Result.fail().message("token失效,请重新登录后再修改密码.");
        }
        // 获取用户id和类型
        Long userId = JwtHelper.getUserId(token);
        Integer userType = JwtHelper.getUserType(token);

        switch (userType) {
            case 1 :
                QueryWrapper<Admin> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("id",userId.intValue());
                Admin admin = adminService.getOne(queryWrapper1);
                return Result.ok(admin);
            case 2 :
                QueryWrapper<Student> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("id",userId.intValue());
                Student student = studentService.getOne(queryWrapper2);
                return Result.ok(student);
            case 3 :
                QueryWrapper<Teacher> queryWrapper3 = new QueryWrapper<>();
                queryWrapper3.eq("id",userId.intValue());
                Teacher teacher = teacherService.getOne(queryWrapper3);
                return Result.ok(teacher);
        }

        return Result.ok();
    }

    @ApiOperation("根据ID更新个人信息")
    @PostMapping("/updateInfoByType")
    public Result updateInfoByType(@ApiParam("token口令") @RequestHeader("token") String token,
                                   @ApiParam("基类对象") @RequestBody Base base) {
        boolean expiration = JwtHelper.isExpiration(token);
        if (expiration) {
            // token过期
            return Result.fail().message("token失效,请重新登录后再修改密码.");
        }
        // 获取用户id和类型
        Long userId = JwtHelper.getUserId(token);
        Integer userType = JwtHelper.getUserType(token);

        switch (userType) {
            case 1 :
                Admin admin = new Admin();
                admin.setId(userId.intValue());
                System.out.println("base = " + base);
                BeanUtils.copyProperties(base,admin);
                return Result.ok(adminService.updateById(admin));
            case 2 :
                Student student = new Student();
                student.setId(userId.intValue());
                BeanUtils.copyProperties(base,student);
                return Result.ok(studentService.updateById(student));
            case 3 :
                Teacher teacher = new Teacher();
                teacher.setId(userId.intValue());
                BeanUtils.copyProperties(base,teacher);
                return Result.ok(teacherService.updateById(teacher));
        }

        return Result.ok();
    }

    // /sms/system/headerImgUpload
    @ApiOperation("文件上传统一入口")
    @PostMapping("/headerImgUpload")
    public Result headerImgUpload(@ApiParam("头像文件") @RequestPart("multipartFile") MultipartFile multipartFile,
                                  HttpServletRequest request) {

        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        String originalFilename = multipartFile.getOriginalFilename();
        int i = originalFilename.lastIndexOf(".");
        String newFileName = uuid.concat(originalFilename.substring(i));

        // 保存文件 将问价放松到第三方/独立的图片服务器
        String portraitPath = "/www/wwwroot/server/upload/".concat(newFileName);
        System.out.println(portraitPath);
        try {
            multipartFile.transferTo(Paths.get(portraitPath));
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 响应图片的路径
        String path = "upload/".concat(newFileName);
        return Result.ok(path);
    }

    @ApiOperation("通过token口令获取当前登录的用户信息的方法")
    @GetMapping("/getInfo")
    public Result getInfoByToken(@ApiParam("token口令") @RequestHeader("token") String token) {
        boolean expiration = JwtHelper.isExpiration(token);
        if(expiration) {
            return Result.build(null, ResultCodeEnum.TOKEN_ERROR);
        }
        //从token中解析出 用户id 和 用户类型
        Long userId = JwtHelper.getUserId(token);
        Integer userType = JwtHelper.getUserType(token);

        Map<String,Object> map = new LinkedHashMap<>();
        switch (userType) {
            case 1:
                Admin admin = adminService.getAdminById(userId);
                map.put("userType",1);
                map.put("user",admin);
                break;
            case 2:
                Student student = studentService.getStudentById(userId);
                map.put("userType",2);
                map.put("user",student);
                break;
            case 3:
                Teacher teacher = teacherService.getTeacherById(userId);
                map.put("userType",3);
                map.put("user",teacher);
                break;
        }

        return Result.ok(map);
    }

    @ApiOperation("登录的方法")
    @PostMapping("/login")
    public Result login(@ApiParam("登录提交的form表单") @RequestBody LoginForm loginForm, HttpServletRequest request) {
        // 验证码校验
        HttpSession session = request.getSession();
        String sessionVerifiCode = code;
        String loginVerifiCode = loginForm.getVerification().toLowerCase();
        if("".equals(sessionVerifiCode)||null == sessionVerifiCode) {
            return Result.fail().message("验证码失效，请刷新后重试");
        }
        if (!loginVerifiCode.equals(sessionVerifiCode.toLowerCase())) {
            return Result.fail().message("有误，请小心输入后重试");
        }

        //准备一个map用于存放响应的数据
        Map<String,Object> map = new LinkedHashMap<>();
        switch (loginForm.getUsertype()){
            case 1:
                try {
                    Admin admin = adminService.login(loginForm);
                    if (null != admin) {
                        // 用户的类型和用户id转换成一个密文，以token的名称向客户端反馈
                        map.put("token",JwtHelper.createToken(admin.getId().longValue(), 1));
                    }else {
                        throw new RuntimeException("用户名或密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
            case 2:
                try {
                    Student student = studentService.login(loginForm);
                    if (null != student) {
                        // 用户的类型和用户id转换成一个密文，以token的名称向客户端反馈
                        map.put("token",JwtHelper.createToken(student.getId().longValue(), 2));
                    }else {
                        throw new RuntimeException("用户名或密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
            case 3:
                try {
                    Teacher teacher = teacherService.login(loginForm);
                    if (null != teacher) {
                        // 用户的类型和用户id转换成一个密文，以token的名称向客户端反馈
                        map.put("token",JwtHelper.createToken(teacher.getId().longValue(), 3));
                    }else {
                        throw new RuntimeException("用户名或密码有误");
                    }
                    return Result.ok(map);
                } catch (RuntimeException e) {
                    e.printStackTrace();
                    return Result.fail().message(e.getMessage());
                }
        }
        return Result.fail().message("查无此用户");
    }

    @ApiOperation("获取验证码图片")
    @GetMapping("/getVerifiCodeImage")
    public void getVerifiCodeImage(HttpServletRequest request, HttpServletResponse response) {
        // 获取图片
        BufferedImage verifiCodeImage = CreateVerifiCodeImage.getVerifiCodeImage();
        // 获取图片上面的验证码
        String verification = new String(CreateVerifiCodeImage.getVerifiCode());
        code = verification;
        // 将验证码图片响应给浏览器
        try {
            ImageIO.write(verifiCodeImage,"JPEG",response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
